<!DOCTYPE html>
<html>
<head>
    <title>Molecular Beam Apparatus</title>
</head>
<body>
<canvas id="physicsCanvas" width="600" height="450" style="border:1px solid #d3d3d3;"></canvas>
<script>
    const canvas = document.getElementById('physicsCanvas');
    const ctx = canvas.getContext('2d');

    // --- Style setup ---
    // Use a font that mimics the hand-drawn style of the original diagram
    ctx.font = "20px 'Comic Sans MS', cursive, sans-serif";
    ctx.lineWidth = 2;
    ctx.strokeStyle = 'black';
    ctx.fillStyle = 'black';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';

    // --- Define geometry ---
    const oven = { x: 50, y: 140, w: 100, h: 100 };
    const chamber = { x: oven.x + oven.w, y: 100, w: 400, h: 180 };
    const pump = { x: 400, w: 60, h: 30 };
    const beamY = oven.y + oven.h / 2; // Central axis of the beam
    const slitGap = 12;

    // --- Draw main apparatus outline ---
    ctx.beginPath();
    // Start from top-left of oven and go clockwise
    ctx.moveTo(oven.x, oven.y);
    ctx.lineTo(chamber.x, oven.y); // Top of oven
    ctx.lineTo(chamber.x, chamber.y); // Riser to chamber top
    ctx.lineTo(chamber.x + chamber.w, chamber.y); // Top of chamber
    ctx.lineTo(chamber.x + chamber.w, chamber.y + chamber.h); // Right wall of chamber
    ctx.lineTo(pump.x + pump.w, chamber.y + chamber.h); // Bottom wall to pump
    ctx.lineTo(pump.x + pump.w, chamber.y + chamber.h + pump.h); // Right wall of pump outlet
    ctx.moveTo(pump.x, chamber.y + chamber.h + pump.h); // Move to left bottom of pump outlet
    ctx.lineTo(pump.x, chamber.y + chamber.h); // Left wall of pump outlet
    ctx.lineTo(chamber.x, chamber.y + chamber.h); // Rest of bottom wall
    ctx.lineTo(chamber.x, oven.y + oven.h); // Riser to oven bottom
    ctx.lineTo(oven.x, oven.y + oven.h); // Bottom of oven
    ctx.closePath(); // Left wall of oven
    ctx.stroke();

    // --- Draw collimating slits ---
    const slit1_x = 230;
    const slit2_x = 310;
    const slitTopY = chamber.y + 40;
    const slitBottomY = chamber.y + chamber.h - 40;

    ctx.beginPath();
    // Slit 1
    ctx.moveTo(slit1_x, slitTopY);
    ctx.lineTo(slit1_x, beamY - slitGap / 2);
    ctx.moveTo(slit1_x, beamY + slitGap / 2);
    ctx.lineTo(slit1_x, slitBottomY);
    // Slit 2
    ctx.moveTo(slit2_x, slitTopY);
    ctx.lineTo(slit2_x, beamY - slitGap / 2);
    ctx.moveTo(slit2_x, beamY + slitGap / 2);
    ctx.lineTo(slit2_x, slitBottomY);
    ctx.stroke();

    // --- Draw molecular beam (dashed lines) ---
    ctx.save(); // Save current state (solid line)
    ctx.setLineDash([6, 4]);
    ctx.beginPath();
    const beamDivergence = 15;
    // Top line of beam
    ctx.moveTo(chamber.x, beamY);
    ctx.lineTo(chamber.x + chamber.w, beamY - beamDivergence);
    // Bottom line of beam
    ctx.moveTo(chamber.x, beamY);
    ctx.lineTo(chamber.x + chamber.w, beamY + beamDivergence);
    ctx.stroke();
    ctx.restore(); // Restore to solid line

    // --- Draw pump outlet arrow and label ---
    const arrowX = pump.x + pump.w / 2;
    const arrowStartY = chamber.y + chamber.h + pump.h;
    const arrowEndY = arrowStartY + 30;
    const arrowHeadSize = 8;
    ctx.beginPath();
    ctx.moveTo(arrowX, arrowStartY);
    ctx.lineTo(arrowX, arrowEndY);
    // Arrowhead
    ctx.moveTo(arrowX, arrowEndY);
    ctx.lineTo(arrowX - arrowHeadSize / 2, arrowEndY - arrowHeadSize);
    ctx.moveTo(arrowX, arrowEndY);
    ctx.lineTo(arrowX + arrowHeadSize / 2, arrowEndY - arrowHeadSize);
    ctx.stroke();
    ctx.fillText('to pump', arrowX, arrowEndY + 20);

    // --- Add labels ---
    ctx.fillText('oven', oven.x + oven.w / 2, oven.y + oven.h / 2);
    ctx.fillText('collimating slits', (slit1_x + slit2_x) / 2, chamber.y - 15);
    ctx.fillText('vacuum', chamber.x + 200, chamber.y + chamber.h - 30);

    // --- Add Figure caption ---
    ctx.font = "18px 'Comic Sans MS', cursive, sans-serif";
    ctx.fillText('Fig. 2.40.', canvas.width / 2 - 100, canvas.height - 50);
</script>
</body>
</html>